package com.cogent.report.xml;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;

import com.cogent.business.domain.ReportMenuDomain;
import com.cogent.common.util.Globals;
import com.cogent.common.util.StringUtil;
import com.cogent.common.util.XmlUtil;
import com.cogent.report.cache.ReportConfigCache;
import com.cogent.report.domain.ReportDisplayFieldDomain;
import com.cogent.report.domain.ReportDomain;
import com.cogent.report.domain.ReportOrderFieldDomain;
import com.cogent.report.domain.ReportSchemaFieldDomain;
import com.cogent.report.domain.ReportSearchFieldDomain;

public class ReportConfigParse {
	 public static final String xmlfile = Globals.getRootPath() + "WEB-INF/config/cogent-ReportConfig.xml";
	 
	 public ReportDomain getReport(String keyid) {
		 Document doc = XmlUtil.loadXmlFormFile(xmlfile);
		 ReportDomain rportDomain = new ReportDomain();
		 Node node = doc.selectSingleNode("//report[@id='" + keyid + "']");
		 if(node != null) {
			 Element e = (Element)node;
			 rportDomain.setId(XmlUtil.getAttributeValue(e, "id"));
			 rportDomain.setCn(XmlUtil.getAttributeValue(e, "cn"));
			 rportDomain.setResourcecode(XmlUtil.getAttributeValue(e, "resourceCode"));
			 rportDomain.setAccess(XmlUtil.getAttributeValue(e, "access"));
			 rportDomain.setStaticcn(XmlUtil.getAttributeValue(e, "staticcn"));
			 rportDomain.setCode(XmlUtil.getAttributeValue(e, "code"));
			 rportDomain.setUnit(XmlUtil.getAttributeValue(e, "unit"));
			 rportDomain.setAmountunit(XmlUtil.getAttributeValue(e, "amountunit"));
			 rportDomain.setType(XmlUtil.getAttributeValue(e, "type"));
			 rportDomain.setLinkurl(XmlUtil.getAttributeValue(e, "linkUrl"));
			 rportDomain.setStatdistrictcode(XmlUtil.getAttributeValue(e, "statdistrictcode"));
			 rportDomain.setIscache(StringUtil.toInt(XmlUtil.getAttributeValue(e, "cache"))==1 ? true : false);
			 Node subnode = node.selectSingleNode("./sql");
			 String sql = XmlUtil.getCdataValue(subnode);
			 rportDomain.setSql(sql);
			 rportDomain.setReporttitle(XmlUtil.getNodeValue(node, "title"));
			 rportDomain.setSearchFieldList(getSearchFieldList(node.selectSingleNode("./searchFields")));
			 rportDomain.setSchemaFieldList(getSchemaFieldList(sql, node.selectSingleNode("./schemaFields")));
			 rportDomain.setDisplayFieldList(getDisplayFieldList(node.selectSingleNode("./displayFields")));
			 rportDomain.setOrderFieldList(getOrderFieldList(node.selectSingleNode("./orderField")));
		 }
		 
		 return rportDomain;
	 }
	 
	 public List parseReport(String name) {
		 List ret = new ArrayList();
		 Document doc = XmlUtil.loadXmlFormFile(xmlfile);
		 Node node = doc.selectSingleNode("//reports[@name='" + name + "']");
		 if(node != null) {
			 List curnode = node.selectNodes("./report");
			 Iterator it = curnode.iterator();
			 while(it.hasNext()) {
				 Element e = (Element)it.next();
				 String id = XmlUtil.getAttributeValue(e, "id");
				 ret.add(ReportConfigCache.get(id));
			 }
		 }
		 
		 return ret;
	 }
	 
	 public ReportMenuDomain parsemenu(String name) {
		 ReportMenuDomain menuDomain = new ReportMenuDomain();
		 Document doc = XmlUtil.loadXmlFormFile(xmlfile);
		 Element node = (Element)doc.selectSingleNode("//reports[@name='" + name + "']");
		 menuDomain.setName(XmlUtil.getAttributeValue(node, "name"));
		 menuDomain.setCn(XmlUtil.getAttributeValue(node, "cn"));
		 
		 return menuDomain;
	 }
	 
	 private List getSearchFieldList(Node node) {
		 List list = new ArrayList();
		 if(node == null)
			 return list;
		 List searchList = node.selectNodes("field");
		 Iterator it = searchList.iterator();
		 while(it.hasNext()) {
			 Element e = (Element)it.next();
			 ReportSearchFieldDomain reportSearchDomain = new ReportSearchFieldDomain();
			 reportSearchDomain.setName(XmlUtil.getAttributeValue(e, "name"));
			 reportSearchDomain.setCn(XmlUtil.getAttributeValue(e, "cn"));
			 reportSearchDomain.setType(XmlUtil.getAttributeValue(e, "type"));
			 reportSearchDomain.setColspan(StringUtil.toInt(XmlUtil.getAttributeValue(e, "colspan"), 1));
			 reportSearchDomain.setTypecode(XmlUtil.getAttributeValue(e, "typecode"));
			 list.add(reportSearchDomain);
		 }
		 
		 return list;
	 }
	 
	 private List getSchemaFieldList(String sql, Node node) {
		 List list = new ArrayList();
		 if(node == null)
			 return list;
		 List searchList = node.selectNodes("field");
		 String tableName = getTableName(sql);
		 Iterator it = searchList.iterator();
		 while(it.hasNext()) {
			 Element e = (Element)it.next();
			 ReportSchemaFieldDomain reportSearchDomain = new ReportSchemaFieldDomain();
			 reportSearchDomain.setName(XmlUtil.getAttributeValue(e, "name"));
			 String dbfield = XmlUtil.getAttributeValue(e, "dbfield");
			 reportSearchDomain.setDbfield(dbfield);
			 String mapfield = XmlUtil.getAttributeValue(e, "mapfield");
			 if(StringUtil.isEmpty(mapfield))
				 mapfield = dbfield;			 
			 reportSearchDomain.setMapfield(mapfield);
			 String curtablename = XmlUtil.getAttributeValue(e, "tablename");
			 if(StringUtil.isEmpty(curtablename))
				 curtablename = tableName;
			 reportSearchDomain.setTablename(curtablename);
			 reportSearchDomain.setType(XmlUtil.getAttributeValue(e, "type"));
			 reportSearchDomain.setSearchType(XmlUtil.getAttributeValue(e, "searchType"));
			 reportSearchDomain.setNullValue(XmlUtil.getAttributeValue(e, "nullValue"));
			 list.add(reportSearchDomain);
		 }
		 
		 return list;
	 }
	 
	 private List getOrderFieldList(Node node) {
		 List list = new ArrayList();
		 if(node == null)
			 return list;
		 List searchList = node.selectNodes("field");
		 Iterator it = searchList.iterator();
		 while(it.hasNext()) {
			 Element e = (Element)it.next();
			 ReportOrderFieldDomain domain = new ReportOrderFieldDomain();
			 domain.setName(XmlUtil.getAttributeValue(e, "name"));
			 domain.setDbfield(XmlUtil.getAttributeValue(e, "dbfield"));			
			 domain.setCn(XmlUtil.getAttributeValue(e, "cn"));
			 list.add(domain);
		 }
		 
		 return list;
	 }
	 
	 private List getDisplayFieldList(Node node) {
		 List list = new ArrayList();
		 if(node == null)
			 return list;
		 List searchList = node.selectNodes("field");
		 Iterator it = searchList.iterator();
		 while(it.hasNext()) {
			 Element e = (Element)it.next();
			 ReportDisplayFieldDomain reportDisplayDomain = new ReportDisplayFieldDomain();
			 reportDisplayDomain.setName(XmlUtil.getAttributeValue(e, "name"));
			 reportDisplayDomain.setCn(XmlUtil.getAttributeValue(e, "cn"));
			 reportDisplayDomain.setDatatype(XmlUtil.getAttributeValue(e, "type"));
			 reportDisplayDomain.setTypecode(XmlUtil.getAttributeValue(e, "typecode"));
			 reportDisplayDomain.setIsdefault(StringUtil.toBoolean(XmlUtil.getAttributeValue(e, "default")));
			 reportDisplayDomain.setOrder(StringUtil.toBoolean(XmlUtil.getAttributeValue(e, "order")));			 
			 list.add(reportDisplayDomain);
		 }
		 
		 return list;
	 }
	 
	 private String getTableName(String sql){
		 String ret = "";
		 sql = sql.toLowerCase();
		 ret = sql.substring(sql.indexOf(" from ") + " from ".length());
		 if(ret.indexOf(" where ")>0)
			 ret = ret.substring(0, ret.indexOf(" where ")).trim();
		 else if(ret.indexOf(" group by ")>0)
			 ret = ret.substring(0, ret.indexOf(" group by ")).trim();
		 else
			 ret = ret.trim();
		 
		 return ret;		 
	 }
}
